package com.emn.fil.defifil.business;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.emn.fil.defifil.iface.IDefi1;

@Component
public class Evaluateur {
	

	
	@Value("${candidats}")
	private Class<IDefi1>[] ICandidats;
	
	
	private List<IDefi1> candidats;
	
	@Autowired
	private Generateur generateur;
	
	@Autowired
	private Solver solver;
	
	@Autowired
	private Comparateur comparateur;
	
	
	public void lancer() {
		
		HashMap<IDefi1, Long> tableauJoueurs = new HashMap<IDefi1, Long>();
		
		candidats = new ArrayList<IDefi1>();
		
		for(Class<IDefi1> ICandidat : ICandidats) {
			
			try {
				IDefi1 candidat = ICandidat.newInstance();
				candidats.add(candidat);
				tableauJoueurs.put(candidat, new Long(0));
			} catch (Exception e) {
				System.out.println("Candidat " + ICandidat + " invalide");
			}
			
		}
		
		System.out.println("Test veracit du tri :");
		testInit();
		
		System.out.println("Test 1 :");
		test1(tableauJoueurs);
		System.out.println("Test 2 :");
		test2(tableauJoueurs);
		System.out.println("Test 3 :");
		test3(tableauJoueurs);
		
		System.out.println(tableauJoueurs);
		
	}
	
	public void testInit() {

		List<Integer> list = generateur.generer(20, 1, 10);
		List<Integer> intrus = generateur.generer(10, 1,10);
		
		List<Integer> solution = solver.trier(new ArrayList<Integer>(list), new ArrayList<Integer>(intrus));

		
		for(IDefi1 candidat : candidats) {

			List<Integer> proposition = null;

			try {
				proposition = candidat.trier(new ArrayList<Integer>(list),  new ArrayList<Integer>(intrus));
			}
			catch(Exception e) {
				System.out.println("Joueur " + candidat.getClass() + " en erreur");
			}
			

			if(!comparateur.isEquals(proposition, solution)) {
				System.out.println("Joueur " + candidat.getClass() + " limin : ");
				System.out.println("Liste à trier : ");
				System.out.println(list);
				System.out.println("Intrus : ");
				System.out.println(intrus);
				System.out.println("Proposition : ");
				System.out.println(proposition);
				System.out.println("Solution : ");
				System.out.println(solution);
			}
			
		}
		
		
	}
	
	/**
	 * Test o aucun intrus n'est dans la liste  trier
	 * @param tab
	 */
	public void test1(HashMap<IDefi1, Long> tab) {
		
		for(int i = 0;i<10;i++) {

			List<Integer> list = generateur.generer(400000, 1, 20000);
			List<Integer> intrus = generateur.generer(800000, 20001, 100000);
			
			
			List<Integer> solution = solver.trier(new ArrayList<Integer>(list), new ArrayList<Integer>(intrus));

			Long begin, end;
			
			Collections.shuffle(candidats);

			for(IDefi1 candidat : candidats) {
				
				List<Integer> proposition = null;
				begin = new Date().getTime();
				try {
					proposition = candidat.trier(new ArrayList<Integer>(list),  new ArrayList<Integer>(intrus));
				}
				catch(Exception e) {
					System.out.println("Joueur " + candidat.getClass() + " en erreur");
				}
				end = new Date().getTime();
				
				if(!comparateur.isEquals(proposition, solution)) {
					System.out.println("Joueur " + candidat.getClass() + " limin");
				}
				
				tab.put(candidat, tab.get(candidat) + (end-begin));
				System.out.println(candidat.getClass() + " : " + (end-begin));
				
			}
			
			System.out.println("I : " + i);
		}
		
	}
	
	/**
	 * Test o les liste se croisent
	 * @param tab
	 */
	public void test2(HashMap<IDefi1, Long> tab) {
		
		for(int i = 0;i<10;i++) {

			List<Integer> list = generateur.generer(40000, 1, 20000);
			List<Integer> intrus = generateur.generer(40000, 1, 20000);
			
			
			List<Integer> solution = solver.trier(new ArrayList<Integer>(list), new ArrayList<Integer>(intrus));

			Long begin, end;
			
			Collections.shuffle(candidats);

			for(IDefi1 candidat : candidats) {

				List<Integer> proposition = null;
				begin = new Date().getTime();
				try {
					proposition = candidat.trier(new ArrayList<Integer>(list),  new ArrayList<Integer>(intrus));
				}
				catch(Exception e) {
					System.out.println("Joueur " + candidat.getClass() + " en erreur");
				}
				end = new Date().getTime();
				
				if(!comparateur.isEquals(proposition, solution)) {
					//System.out.println(proposition);
					System.out.println("Joueur " + candidat.getClass() + " limin");
				}
				
				tab.put(candidat, tab.get(candidat) + (end-begin));
				System.out.println(candidat.getClass() + " : " + (end-begin));
				
			}
			
			System.out.println("I : " + i);
		}
		
	}
	
	/**
	 * 
	 * @param tab
	 */
	public void test3(HashMap<IDefi1, Long> tab) {
		
		for(int i = 0;i<10;i++) {

			List<Integer> list = generateur.generer(100000, 1, 100);
			List<Integer> intrus = generateur.generer(100000, 1, 100);
			
			
			List<Integer> solution = solver.trier(new ArrayList<Integer>(list), new ArrayList<Integer>(intrus));

			Long begin, end;
			
			Collections.shuffle(candidats);

			for(IDefi1 candidat : candidats) {
				

				List<Integer> proposition = null;
				begin = new Date().getTime();
				try {
					proposition = candidat.trier(new ArrayList<Integer>(list),  new ArrayList<Integer>(intrus));
				}
				catch(Exception e) {
					System.out.println("Joueur " + candidat.getClass() + " en erreur");
				}
				end = new Date().getTime();
				
				if(!comparateur.isEquals(proposition, solution))
					System.out.println("Joueur " + candidat.getClass() + " limin");
				
				tab.put(candidat, tab.get(candidat) + (end-begin));
				System.out.println(candidat.getClass() + " : " + (end-begin));
				
			}
			
			System.out.println("I : " + i);
		}
		
	}
	
}
